/** \file    io.cpp
  * \brief   images input/output.
  * \date    2002, 2003
  * \author  Fedor Chelnokov
  * \version $Header: /home/cscom1r4/cvsroot/cs/imglib/src/io.cpp,v 1.4 2007/07/12 20:30:10 cscom1r4 Exp $
  */

#include "imglib/io.h"
#include "imglib/bmp.h"
#include "imglib/tga.h"

using std::string;

namespace img {

size_t writer::write_autoformat(const std::string & path, const byte_image & img, bool alpha)
{
	size_t n = path.find_last_of("./\\");
	if (n == size_t(string::npos) || n == path.length()-1 || path[n] != '.')
		throw io_error("can not determine format from image file name", path);
	return write(path, path.substr(n+1), img, alpha);
}

enum ourf { unkf, bmpf, tgaf };

static ourf ourf_from_ext(const string & filename)
{
	unsigned l = filename.length();
	if (l < 4)
		return unkf;
	string last4 = filename.substr(l-4, 4);
	if (_stricmp(last4.c_str(), ".BMP") == 0)
		return bmpf;
	if (_stricmp(last4.c_str(), ".TGA") == 0)
		return tgaf;
	return unkf;
}

bool our_reader::ping(const std::string & path, file_info * info) const
{
	switch (ourf_from_ext(path)) {
	case bmpf:
		return bmp::ping(path, info);
	case tgaf:
		return tga::ping(path, info);
	case unkf:
	default:
		if (bmp::ping(path, info))
			return true;
		else
			return tga::ping(path, info);
	}
}

bool our_reader::ping(const std::string & path, const std::string & format, file_info * info) const
{
	if (_stricmp(format.c_str(), "BMP") == 0)
		return bmp::ping(path, info);
	if (_stricmp(format.c_str(), "TGA") == 0)
		return tga::ping(path, info);
	return false;
}

bool our_reader::fast_ping() const
{
	return true;
}

void our_reader::read(const std::string & path, byte_image & img) const
{
	switch (ourf_from_ext(path)) {
	case bmpf:
		return bmp::read(path, img);
	case tgaf:
		return tga::read(path, img);
	case unkf:
	default:
		try {
			return bmp::read(path, img);
		}
		catch (const io_error &) {
			return tga::read(path, img);
		}
	}
}

void our_reader::read(const std::string & path, const std::string & format, byte_image & img) const
{
	if (_stricmp(format.c_str(), "BMP") == 0)
		return bmp::read(path, img);
	if (_stricmp(format.c_str(), "TGA") == 0)
		return tga::read(path, img);
	throw unsupported(unsupported::file_type, path);
}

void our_reader::formats(ext_vec & f) const
{
	f.clear();
	f.push_back("BMP");
	f.push_back("TGA");
}

std::string our_reader::search_str() const
	{ return "*.BMP;*.TGA"; }

size_t our_writer::write(const std::string & path, const std::string & format, const byte_image & img, bool alpha)
{
	if (_stricmp(format.c_str(), "BMP") == 0) {
		if (alpha)
			return bmp::write32bit(path.c_str(), img);
		else
			return bmp::write24bit(path.c_str(), img);
	} else
	if (_stricmp(format.c_str(), "TGA") == 0) {
		if (alpha)
			return tga::write32bit(path.c_str(), img);
		else
			return tga::write24bit(path.c_str(), img);
	}
	else
		throw io_error("file format is not supported", format);
}

void our_writer::formats(ext_vec & f) const
{
	f.clear();
	f.push_back("BMP");
	f.push_back("TGA");
}

std::string our_writer::search_str() const
	{ return "*.BMP;*.TGA"; }

} //namespace img
